package com.xy.blog.user.service.impl;

import com.xy.blog.core.id.SnowflakeIdWorker;
import com.xy.blog.core.springmvc.result.page.PageReq;
import com.xy.blog.core.springmvc.result.page.PageResp;
import com.xy.blog.user.controller.model.req.query.UserTemplateQuery;
import com.xy.blog.user.dao.impl.AttrDictDaoImpl;
import com.xy.blog.user.dao.impl.UserTemplateDaoImpl;
import com.xy.blog.user.dao.model.AttrDictDO;
import com.xy.blog.user.dao.model.UserTemplateDO;
import com.xy.blog.user.dao.model.rel.UserTemplateAttrRelDO;
import com.xy.blog.user.exception.UserException;
import com.xy.blog.user.exception.constants.UserTemplateErrorCode;
import com.xy.blog.user.mapstruct.AttrDictConverter;
import com.xy.blog.user.mapstruct.UserTemplateConverter;
import com.xy.blog.user.service.IUserTemplateService;
import com.xy.blog.user.service.model.AttrDictBO;
import com.xy.blog.user.service.model.UserTemplateBO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @author zanhonglei
 * @version V1.0
 * @Description:
 * @date 2019/11/17 5:39 下午
 */
@Service
public class UserTemplateServiceImpl implements IUserTemplateService {

    @Autowired
    private UserTemplateDaoImpl userTemplateDaoImpl;

    @Autowired
    private UserTemplateConverter userTemplateConverter;

    @Autowired
    private AttrDictDaoImpl attrDictDaoImpl;

    @Autowired
    private AttrDictConverter attrDictConverter;

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void saveUserTemplate( String name,String code,Long defaultOpenAccountAttrId,List<Long> userAttrIds) {
        UserTemplateDO selectIsExits = new UserTemplateDO();
        selectIsExits.setName(name);
        if (userTemplateDaoImpl.selectCount(selectIsExits) > 0) {
            throw new UserException(UserTemplateErrorCode.USER_TEMPLATE_EXITS);
        }
        Long userTemplateId = SnowflakeIdWorker.generateId();
        UserTemplateDO userTemplateDO = new UserTemplateDO();
        LocalDateTime now = LocalDateTime.now();
        userTemplateDO.setCreateTime(now);
        userTemplateDO.setUpdateTime(now);
        userTemplateDO.setId(userTemplateId);
        userTemplateDO.setName(name);
        userTemplateDO.setCode(code);
        userTemplateDO.setDefaultOpenAccountAttrId(defaultOpenAccountAttrId);
        userTemplateDaoImpl.save(userTemplateDO);

        userAttrIds.forEach(userAttrId -> {
            UserTemplateAttrRelDO userTemplateAttrRelDO = new UserTemplateAttrRelDO();
            userTemplateAttrRelDO.setId(SnowflakeIdWorker.generateId());
            userTemplateAttrRelDO.setUserTemplateId(userTemplateId);
            userTemplateAttrRelDO.setUserAttrId(userAttrId);
            userTemplateDaoImpl.saveRel(userTemplateAttrRelDO);
        });

    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void updateUserTemplate(Long id, String name, List<Long> userAttrIds) {
        UserTemplateAttrRelDO userTemplateAttrRelDO = new UserTemplateAttrRelDO();
        userTemplateAttrRelDO.setUserTemplateId(id);

        List<UserTemplateAttrRelDO> select = userTemplateDaoImpl.selectRel(userTemplateAttrRelDO);

        List<Long> increaseItem = new ArrayList<>();
        List<Long> decreaseItem = new ArrayList<>();
        //当前的属性id集合
        List<Long> exitsUserAttrIds = new ArrayList<>();

        select.forEach(item -> {
            exitsUserAttrIds.add(item.getUserAttrId());
        });

        //需要添加的属性id
        userAttrIds.forEach(userAttrId -> {
            if (!exitsUserAttrIds.contains(userAttrId)) {
                increaseItem.add(userAttrId);
            }
        });

        //需要删除的属性id
        exitsUserAttrIds.forEach(userAttrId -> {
            if (!userAttrIds.contains(userAttrId)) {
                decreaseItem.add(userAttrId);
            }
        });


        decreaseItem.forEach(deleteId -> {
            userTemplateDaoImpl.deleteRelById(deleteId);
        });

        increaseItem.forEach(addId -> {
            UserTemplateAttrRelDO needAdd = new UserTemplateAttrRelDO();
            needAdd.setUserAttrId(addId);
            needAdd.setUserTemplateId(id);
            userTemplateDaoImpl.saveRel(needAdd);
        });

    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void deleteById(Long id) {
        userTemplateDaoImpl.deleteById(id);
        userTemplateDaoImpl.deleteRelByTemplateId(id);
    }


    @Override
    public PageResp<UserTemplateBO> listUserTemplate(PageReq<UserTemplateQuery> req) {
        UserTemplateQuery params = req.getParams();
        PageResp<UserTemplateDO> userTemplateDOPageResp = userTemplateDaoImpl.listByPage(req);
        PageResp<UserTemplateBO> resp = userTemplateConverter.do2Bo(userTemplateDOPageResp);
        resp.getList().forEach(item->{
            Long userTemplateId = item.getId();
            UserTemplateAttrRelDO userTemplateAttrRelDO = new UserTemplateAttrRelDO();
            userTemplateAttrRelDO.setUserTemplateId(userTemplateId);
            List<UserTemplateAttrRelDO> userTemplateAttrRelDOS = userTemplateDaoImpl.selectRel(userTemplateAttrRelDO);
            List<AttrDictBO> attrDictBOS = new ArrayList<>();
            userTemplateAttrRelDOS.forEach(attr->{
                Long userAttrId = attr.getUserAttrId();
                AttrDictDO byId = attrDictDaoImpl.getById(userAttrId);
                attrDictBOS.add(attrDictConverter.do2Bo(byId));
            });
            item.setDefaultOpenAccountAttr(attrDictConverter.do2Bo(attrDictDaoImpl.getById(item.getDefaultOpenAccountAttrId())));
            item.setAttrDict(attrDictBOS);
        });
        return resp;
    }


    @Override
    public List<AttrDictBO> listUserTemplateAttrByTemplateId(Long id) {
        List<AttrDictBO> returnObj = new ArrayList<>();
        UserTemplateAttrRelDO userTemplateAttrRelDO = new UserTemplateAttrRelDO();
        userTemplateAttrRelDO.setUserTemplateId(id);
        List<UserTemplateAttrRelDO> userTemplateAttrRelDOS = userTemplateDaoImpl.selectRel(userTemplateAttrRelDO);
        userTemplateAttrRelDOS.forEach(item->{
            AttrDictDO attrDictDO = attrDictDaoImpl.getById(item.getUserAttrId());
            returnObj.add(attrDictConverter.do2Bo(attrDictDO));
        });
        return returnObj;
    }

    @Override
    public List<UserTemplateBO> listByName(String name) {
        UserTemplateDO userTemplateDO = new UserTemplateDO();
        userTemplateDO.setName(name);
        return userTemplateConverter.do2Bo(userTemplateDaoImpl.select(userTemplateDO));
    }


}
